// Copyright (C) 1953-2022 NUDT
// Verilog module name - hcp_buffer_output 
// Version: V4.0.0.20220531
// Created:
//         by - fenglin 
////////////////////////////////////////////////////////////////////////////
// Description:
//         transmit process of host.
//             -top module.
///////////////////////////////////////////////////////////////////////////

`timescale 1ns/1ps

module hcp_buffer_output
(
       i_clk,
       i_rst_n,
       
       iv_pkt_type_ctrl,
	   iv_pkt_bufid_ctrl,
       i_mac_entry_hit_ctrl,
       iv_pkt_inport_ctrl,
       i_pkt_bufid_wr_ctrl,
       
       ov_pkt_bufid,
       o_pkt_bufid_wr,
       i_pkt_bufid_ack, 
       
       ov_pkt_raddr,
       o_pkt_rd,
       i_pkt_raddr_ack,
       
       iv_pkt_data,
       i_pkt_data_wr,   
       
       ov_hcp_data   ,
       o_hcp_data_wr         
);

// I/O
// clk & rst
input                  i_clk           ;   
input                  i_rst_n         ;

//tsntag & bufid input from host_port
input          [2:0]   iv_pkt_type_ctrl;
input          [8:0]   iv_pkt_bufid_ctrl;
input                  i_mac_entry_hit_ctrl;
input          [5:0]   iv_pkt_inport_ctrl;
input                  i_pkt_bufid_wr_ctrl;
//receive pkt from PCB  
input       [133:0]    iv_pkt_data;
input                  i_pkt_data_wr;
// pkt_bufid to PCB in order to release pkt_bufid
output     [8:0]       ov_pkt_bufid;
output                 o_pkt_bufid_wr;
input                  i_pkt_bufid_ack; 
// read address to PCB in order to read pkt data       
output     [15:0]      ov_pkt_raddr;
output                 o_pkt_rd;
input                  i_pkt_raddr_ack;
// transmit pkt to phy     
output     [8:0]       ov_hcp_data  ;
output                 o_hcp_data_wr;

wire       [15:0]      wv_descriptor_nqm2ntx;
wire                   w_descriptor_wr_nqm2ntx;
wire                   w_descriptor_ready_ntx2nqm;
control_queue_management control_queue_management_inst(
.i_clk(i_clk),
.i_rst_n(i_rst_n),

.iv_pkt_type_ctrl     (iv_pkt_type_ctrl    ),
.iv_pkt_bufid_ctrl    (iv_pkt_bufid_ctrl   ),
.i_mac_entry_hit_ctrl (i_mac_entry_hit_ctrl),
.iv_pkt_inport_ctrl   (iv_pkt_inport_ctrl  ),
.i_pkt_bufid_wr_ctrl  (i_pkt_bufid_wr_ctrl ),

.ov_descriptor        (wv_descriptor_nqm2ntx),
.o_descriptor_wr      (w_descriptor_wr_nqm2ntx),
.i_descriptor_ready   (w_descriptor_ready_ntx2nqm)
);
control_tx control_tx_inst(
.i_clk(i_clk),
.i_rst_n(i_rst_n),

.iv_pkt_descriptor(wv_descriptor_nqm2ntx),
.i_pkt_descriptor_wr(w_descriptor_wr_nqm2ntx),
.o_pkt_descriptor_ready(w_descriptor_ready_ntx2nqm),

.ov_pkt_bufid(ov_pkt_bufid),
.o_pkt_bufid_wr(o_pkt_bufid_wr),
.i_pkt_bufid_ack(i_pkt_bufid_ack),  

.ov_pkt_raddr(ov_pkt_raddr),
.o_pkt_rd(o_pkt_rd),
.i_pkt_raddr_ack(i_pkt_raddr_ack),

.iv_pkt_data(iv_pkt_data),
.i_pkt_data_wr(i_pkt_data_wr),

.ov_hcp_data  (ov_hcp_data  ),
.o_hcp_data_wr(o_hcp_data_wr)
);

(*MARK_DEBUG="true"*) reg  [15:0]  rv_pkt_tx_counter/*synthesis noprune*/;
(*MARK_DEBUG="true"*) reg  r_data_tx_valid;
always @(posedge i_clk or negedge i_rst_n) begin
    if (!i_rst_n) begin
        rv_pkt_tx_counter <= 16'b0;
		r_data_tx_valid    <=  1'b0;
    end
    else begin
	    r_data_tx_valid <= o_hcp_data_wr;
        if((!r_data_tx_valid) && o_hcp_data_wr)begin
			rv_pkt_tx_counter <= rv_pkt_tx_counter + 1'b1;
        end
        else begin
            rv_pkt_tx_counter <=  rv_pkt_tx_counter;
        end		
	end	
end
endmodule